/*
 * Author: hujingfei914@msn.com
 * Date:   2010-10-14
 * Description: A 3-d aircraft model containing position and orientation
 */

#include "Aircraft.h"

CAircraft::CAircraft(void)
{
}

CAircraft::~CAircraft(void)
{
}

CAircraft::CAircraft(
 const char *filePath,
 float x, float y, float z,
 double xrot, double yrot, double zrot)
{
	meshes_ = loadVRML((char *)filePath);
	x_ = x;
	y_ = y;
	z_ = z;

	xrot_ = xrot;
	yrot_ = yrot;
	zrot_ = zrot;
}

void CAircraft::draw(void)
{
	glPushMatrix();
		glPushMatrix();
		glDisable(GL_BLEND);
		glColor3f(1.0f, 1.0f, 1.0f);
		glTranslatef(x_, y_, z_);
		// To make the aircraft's coordinate system same as the test environment's coordinate system.
		// First rotate around the x-axis, means pitch
		glRotatef(xrot_, 1.0f, 0.0f, 0.0f);
		// Second rotate around the y-axis, means heading
		glRotatef(yrot_, 0.0f, 1.0f, 0.0f);		
		// Third rotate around the z-axis, means roll
		glRotatef(zrot_, 0.0f, 0.0f, 1.0f);
		glEnable(GL_DEPTH_TEST);
		glBegin(GL_TRIANGLES);
			for ( int i = 0; i < (int)meshes_.size(); i++ ) {
				for ( int j = 0; j < (int)meshes_[i].numFaces; j++ ) {
					glNormal3f(
						meshes_[i].normals[(int) meshes_[i].faces[j].x].x, 
						meshes_[i].normals[(int) meshes_[i].faces[j].x].y, 
						meshes_[i].normals[(int) meshes_[i].faces[j].x].z);
					glVertex3f(
						meshes_[i].vertices[(int) meshes_[i].faces[j].x].x, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].x].y, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].x].z);

					glNormal3f(
						meshes_[i].normals[(int) meshes_[i].faces[j].y].x, 
						meshes_[i].normals[(int) meshes_[i].faces[j].y].y, 
						meshes_[i].normals[(int) meshes_[i].faces[j].y].z);
					glVertex3f(
						meshes_[i].vertices[(int) meshes_[i].faces[j].y].x, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].y].y, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].y].z);

					glNormal3f(
						meshes_[i].normals[(int) meshes_[i].faces[j].z].x, 
						meshes_[i].normals[(int) meshes_[i].faces[j].z].y, 
						meshes_[i].normals[(int) meshes_[i].faces[j].z].z);
					glVertex3f(
						meshes_[i].vertices[(int) meshes_[i].faces[j].z].x, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].z].y, 
						meshes_[i].vertices[(int) meshes_[i].faces[j].z].z);
				}
			}
		glEnd();
		glEnable(GL_BLEND);
		glPopMatrix();
	glPopMatrix();
}

/*
 * Update the aircraft model's position and orientation
 */
void CAircraft::updatePositionAndOrientation(UINT nFlags, CPoint point)
{
	static GLfloat m_fLastX = (GLfloat)point.x;
	static GLfloat m_fLastY = (GLfloat)point.y;

	int diffX = (int)(point.x - m_fLastX);
	int diffY = (int)(point.y - m_fLastY);

	m_fLastX = (GLfloat)point.x;
	m_fLastY = (GLfloat)point.y;

	// Left mouse button
	if (nFlags & MK_LBUTTON) 
	{
		xrot_ += (float)0.5f * diffY;
		if ((xrot_ > 360.0f) || (xrot_ < -360.0f)) 
		{
			xrot_ = 0.0f;
		}

		yrot_ += (float)0.5f * diffX;
		if ((yrot_ > 360.0f) || (yrot_ < -360.0f)) 
		{
			yrot_ = 0.0f;
		}
	}

	// Right mouse button
	else if (nFlags & MK_RBUTTON) 
	{
		z_ -= (float)1.5f * diffY;
	}
	
	// Middle mouse button
	else if (nFlags & MK_MBUTTON) {
		x_ += (float)0.5f * diffX;
		y_ -= (float)0.5f * diffY;
	}

}

/*
 * Update the aircraft model's position and orientation
 */
void CAircraft::updatePositionAndOrientation(const FlyState& flyState)
{
	xrot_ = flyState.theta;		// Pitch
	yrot_ = flyState.psi;		// Roll
	zrot_ = flyState.phi;		// Heading
}